package com.yyzw.activiti.modeler.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yyzw.activiti.modeler.model.ResultVo;
import com.yyzw.activiti.modeler.service.ActivitiModelerService;
import com.yyzw.activiti.modeler.util.ModelNodeJsonData;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;

import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

@Controller
@RequestMapping(value = "activiti")
public class ActivitiModelerController {

    private static final Logger logger = LoggerFactory.getLogger(ActivitiModelerController.class);

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    ObjectMapper objectMapper;

    @Autowired
    ActivitiModelerService activitiModelerService;

    @RequestMapping(value = "index")
    public String activitiListIndex(ModelMap model){
        //加载当前包含的项目
        List<Model> activitiLists = repositoryService.createModelQuery().list();
        model.addAttribute("lists",activitiLists);
        return "activiti_list_index";
    }


    @RequestMapping("/create")
    public String  createActiviti(HttpServletRequest request, HttpServletResponse response) throws Exception{
        Model model = repositoryService.newModel();

        String name = "新建流程";
        String description = "";
        int revision = 1;
        String key = "processKey";

        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
        modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
        modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);

        model.setName(name);
        model.setKey(key);
        model.setMetaInfo(modelNode.toString());

        repositoryService.saveModel(model);
        String id = model.getId();

        //完善ModelEditorSource
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace",
                "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
        return "redirect:/modeler/modeler.html?modelId=" + id;

    }


    @ResponseBody
    @RequestMapping(value = "/delDeploy",method = RequestMethod.POST)
    public ResultVo delDeploy(String modelId){
        try {
            List<ActivityImpl> activityList = activitiModelerService.getActivityList(modelId);
            for (ActivityImpl activity: activityList) {
                String nodeId = activity.getId();
                if(StringUtils.isEmpty(nodeId)||"start".equals(nodeId)||"end".equals(nodeId)){
                    continue;
                }
                /**接触节点和代办关联*/
                activitiModelerService.deleteByNodeId(nodeId);
                repositoryService.deleteDeployment(modelId,true);
            }
        } catch (Exception e) {
           logger.error(e.getMessage(),e);
            return new ResultVo("000010","删除失败");
        }
        return new ResultVo("000000","删除成功");
    }


    /**
     * 流程的发布
     * @return
     * @param modelId
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "deplayProc")
    public ResultVo deplayActivitiProc(String modelId) throws Exception{

        Model modelData = repositoryService.getModel(modelId);
        byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());
        if(bytes == null){
            return new ResultVo("000011","模型为空");
        }
        JsonNode modelNode = null;
        try {

            modelNode =  objectMapper.readTree(bytes);
            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            if(model.getProcesses().size()==0){
                return new ResultVo("000012","数据不符合要求");
            }
            byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
            //发布流程
            String processName = modelData.getName() + ".bpmn20.xml";
            String convertToXml = new String(bpmnBytes);
            System.out.println(convertToXml);
            Deployment deployment = repositoryService.createDeployment().name(modelData.getName())
                    .addString(processName, new String(bpmnBytes, "utf-8"))
                    .deploy();

            modelData.setDeploymentId(deployment.getId());
            repositoryService.saveModel(modelData);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResultVo("000000","发布成功");
    }


    /**
     * 删除流程实例
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "delProc")
    public ResultVo delModel(HttpServletRequest request) throws  Exception{
        String modelId = request.getParameter("modelId");
        repositoryService.deleteModel(modelId);
        return new ResultVo("000000","删除实例成功");
    }
}
